package cn.bs.busuo.passport.service.impl;

import cn.bs.busuo.passport.dao.cache.IUserCacheRepository;
import cn.bs.busuo.passport.dao.persist.repository.IUserRepository;
import cn.bs.busuo.passport.pojo.cachevo.CacheUserStandardVO;
import cn.bs.busuo.passport.pojo.entity.User;
import cn.bs.busuo.passport.pojo.param.UserLoginInfoParam;
import cn.bs.busuo.passport.pojo.vo.UserLoginInfoVO;
import cn.bs.busuo.passport.pojo.vo.UserLoginResultVO;
import cn.bs.busuo.passport.pojo.vo.UserStandardVO;
import cn.bs.busuo.passport.service.IUserService;
import cn.bs.busuo.common.enumerator.ServiceCode;
import cn.bs.busuo.common.ex.ServiceException;
import cn.bs.busuo.common.pojo.authentication.CurrentPrincipal;
import cn.bs.busuo.common.pojo.po.UserStatePO;
import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j

@Service
public class UserServiceImpl implements IUserService {

    @Value("${busuo.jwt.secret-key}")
    private String secretKey;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private IUserRepository userRepository;
    @Autowired
    private IUserCacheRepository userCacheRepository;

    @Override
    public UserLoginResultVO login(UserLoginInfoParam userLoginInfoParam, String remoteAddr, String userAgent) {
        String username = userLoginInfoParam.getUsername();
        UserLoginInfoVO queryResult = userRepository.getLoginInfoByUsername(username);
        System.out.println(userLoginInfoParam);
        System.out.println(queryResult);
        if (queryResult == null) {
            String message = "登录失败，用户名或密码错误！【1】";
            throw new ServiceException(ServiceCode.ERROR_UNAUTHORIZED, message);
        }

        if (queryResult.getEnable() != 1) {
            String message = "登录失败，此账号已经被禁用！";
            throw new ServiceException(ServiceCode.ERROR_UNAUTHORIZED_DISABLED, message);
        }

        String password = userLoginInfoParam.getPassword();
        if (!passwordEncoder.matches(password, queryResult.getPassword())) {
            String message = "登录失败，用户名或密码错误！【2】";
            throw new ServiceException(ServiceCode.ERROR_UNAUTHORIZED, message);
        }

        // TODO 向登录日志表(account_login_log)中插入数据

        List<String> permissions = queryResult.getPermissions();
        String authoritiesJsonString = JSON.toJSONString(permissions);

        UserStatePO userStatePO = new UserStatePO();
        userStatePO.setAuthoritiesJsonString(authoritiesJsonString);
        userStatePO.setEnable(1);
//redis缓存用户数据
        userCacheRepository.saveUserState(queryResult.getId(), userStatePO);

        Map<String, Object> claims = new HashMap<>();
        claims.put("id", queryResult.getId());
        claims.put("username", queryResult.getUsername());
        claims.put("remoteAddr", remoteAddr);
        claims.put("userAgent", userAgent);
        String jwt = Jwts.builder()
                // Header
                .setHeaderParam("alg", "HS256")
                .setHeaderParam("typ", "JWT")
                // Payload 正文内容
                .setClaims(claims)
                //设置过期时间
                // .setExpiration(new Date(System.currentTimeMillis() + 60 * 1000))
                // Verify Signature验证签名
                .signWith(SignatureAlgorithm.HS256, secretKey)
                // 完成
                .compact();

        UserLoginResultVO loginResult = new UserLoginResultVO();
        BeanUtils.copyProperties(queryResult, loginResult);
        loginResult.setToken(jwt);
//        System.out.println("这是新生成回去的jwt:" + jwt);
        //更新数据库
        User user = new User();
        user.setUserAgent(userAgent);
        user.setLastLoginIp(remoteAddr);
        user.setId(queryResult.getId());
        user.setGmtLastLogin(DateTime.now());
        userRepository.setLastAddrAndAgent(user);
        //插入用户信息缓存
        UserStandardVO userStandardVO = userRepository.selectBaseInformation(user.getId());
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String lastLogin = sdf2.format(userStandardVO.getGmtLastLogin());
        CacheUserStandardVO cacheUserStandardVO = new CacheUserStandardVO();
        BeanUtils.copyProperties(userStandardVO, cacheUserStandardVO);
        cacheUserStandardVO.setGmtLastLogin(lastLogin);
        userCacheRepository.saveUserInformation(user.getId(), cacheUserStandardVO);
        return loginResult;
    }

    @Override
    public void logout(CurrentPrincipal currentPrincipal) {
        Long userId = currentPrincipal.getId();
        userCacheRepository.deleteUserState(userId);
    }
}